/*
 * math.h
 *
 * Copyright 2011 Pieter Agten
 *
 * This file is part of Yarf.
 *
 * Yarf is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Yarf is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Yarf.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @file   math.h
 * @author Pieter Agten (pieter.agten@gmail.com)
 * @date   2 nov 2011
 * @brief  Complements the <%math.h> header file with some basic math functions
 *         and macros.
 */

#ifndef MATH_H
#define MATH_H

#include <math.h>
#include <stdint.h>

/**
 * Returns the smallest of two numbers.
 *
 * @param a  the first number
 * @param b  the second number
 * @return a if a < b and b otherwise
 */
#define MIN(a,b) ((a)<(b)?(a):(b))

/**
 * Returns the largest of two numbers.
 *
 * @param a  the first number
 * @param b  the second number
 * @return a if a > b and b otherwise
 */
#define MAX(a,b) ((a)>(b)?(a):(b))

/**
 * Returns the sign of a number.
 *
 * @param x  the number of which to return the sign
 * @return 1 if x >= 0 and -1 otherwise
 */
#define SIGNUM(x) (((x) < 0)?(-1):(1))

/**
 * Bounds a given value to a given minimum and maximum value.
 *
 * @param min  the minimum value
 * @param x    the value to bound
 * @param max  the maximum value
 * @return min if x < min, or max if x > max, or x otherwise
 */
#define BOUNDS(min,x,max)  MAX(min,MIN(x,max))


/**
 * Returns the square of a floating point number.
 * 
 * @param x the number of which to return the square
 * @return x * x
 */
inline float
fsquare(float x)
{
  return x * x;
}

/**
 * Returns the square of a long integer, if it fits within the representable
 * range of unsigned long integers.
 * 
 * @param x the number of which to return the square
 * @return x * x, if that fits within the representable range of unsigned long
 *         integers, or an undefined value otherwise
 */
inline unsigned long
lsquare(long x)
{
  return x * x; //TODO: pre-convert to unsigned longs?
}

/**
 * Returns the square of an unsigned 16-bit integer.
 * 
 * @param x the number of which to return the square
 * @return x * x
 */
inline uint32_t
uint16_square(uint16_t x)
{
  return (uint32_t)x * x;
}


#endif //MATH_H
